﻿using System.Collections;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;
using System;
using Puerts;
using Object = UnityEngine.Object;

namespace UnityLuaConsole.Assets.Code {
    public class LuaCnsoleManager : MonoBehaviour {
        [SerializeField] LuaConsole luaConsole;
        [SerializeField] UnityMethodsEvents unityMethodsEvents;
        JsEnv luaEngine;

        string script = @"    
		-- defines a factorial function
		function fact (n)
			if (n == 0) then
				return 1
			else
				return n*fact(n - 1)
			end
        func(""n"")
		end
        
		return fact(5)";

        private void Awake() {
            MoonSharpFactorial();
            luaConsole.SetExecuteAction(ExecuteInputCommand);
            luaEngine = JsManager.Instance.GetJsEnv();
            DontDestroyOnLoad(gameObject);
        }

        private void Update()
        {
            if(ShouldToggleConsole())
                luaConsole.gameObject.SetActive(!luaConsole.gameObject.activeSelf);
        }

        private float fclickTime = 0;
        private int clickCount = 0;
        bool ShouldToggleConsole()
        {
#if DEBUG && UNITY_ANDROID
            if (Input.GetMouseButtonDown(0) || Input.touchCount > 0)
            {
                if (Vector2.Distance(new Vector2(Screen.width, 0), Input.mousePosition) < 100)
                {
                    if (Time.time - fclickTime < 0.35f)
                        clickCount++;
                    else
                        clickCount = 0;
                    fclickTime = Time.time;
                    if (clickCount == 10)
                        return true;
                }
            }
#endif
            return Input.GetKeyDown (KeyCode.BackQuote);
        }
        private void ExecuteInputCommand(string expression) {
            JsManager.Instance.GetJsEnv().Eval(expression);
        }

        void MoonSharpFactorial() {
            // UserData.RegisterAssembly();
            //
            // UserData.RegisterType<Vector3>();
            // UserData.RegisterType<KeyCode>();
            // UserData.RegisterType<Input>();
            // UserData.RegisterType<GameObject>();
            //
            // UserData.RegisterType<Transform>();
            //
            // //UserData.RegisterProxyType<TransformProxy, Transform>(r => new TransformProxy(r));
            //
            //
            // UserData.RegisterType<EventArgs>();
            // UserData.RegisterType<UnityMethodsEvents.Events>();
            //
            // luaEngine = new Script();
            // luaEngine.Globals["Vector3"] = UserData.CreateStatic<Vector3>();
            // luaEngine.Globals["KeyCode"] = UserData.CreateStatic<KeyCode>();
            // luaEngine.Globals["Input"] = UserData.CreateStatic<Input>();
            // luaEngine.Globals["GameObject"] = UserData.CreateStatic<GameObject>();
            //
            // luaEngine.Globals["unityEvents"] = unityMethodsEvents.events;
            // luaEngine.Globals["Circle"] = GameObject.Find("Circle").transform;
            //luaEngine.Options.DebugPrint = s => { luaConsole.AddLuaLog(s); };
            Debug.unityLogger.logHandler = new luaLogHandler(luaConsole);
        }

        class  luaLogHandler:ILogHandler
        {
            private ILogHandler unityhandler;
            private LuaConsole _luaConsole;

            public luaLogHandler(LuaConsole console)
            {
                _luaConsole = console;
                unityhandler = Debug.unityLogger.logHandler;
                Debug.unityLogger.logHandler = this;
            }

            /// <summary>
            ///   <para>A variant of ILogHandler.LogFormat that logs an exception message.</para>
            /// </summary>
            /// <param name="exception">Runtime Exception.</param>
            /// <param name="context">Object to which the message applies.</param>
            public void LogException(Exception exception, Object context)
            {
                unityhandler.LogException(exception,context);
                //_luaConsole.AddLuaLog(exception.Message);
            }

            public void LogFormat(LogType logType, Object context, string format, params object[] args)
            {
                unityhandler.LogFormat(logType,context,format,args);
                _luaConsole.AddLuaLog(string.Format(format,args));
            }
        }
    }
}
